#include "stm32f10x.h"                  // Device header
#include <stdio.h>
#include <stdarg.h>
#include "string.h" //使用strcmp头文件

uint8_t Serial_RxFlag;

uint8_t receiveFlag=1;


/**
  * 函    数：串口初始化
  * 参    数：无
  * 返 回 值：无
  */
void Serial_Init(void)
{
	/*开启时钟*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);	//开启USART1的时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);	//开启GPIOA的时钟
	
	/*GPIOA_9初始化*/
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);					//将PA9引脚初始化为复用推挽输出
	
		//GPIOA_10
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//上拉输入模式
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
//	//选择A6为亮灯口
//	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出模式
//	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
//	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
//	GPIO_Init(GPIOA, &GPIO_InitStructure);		
	
	/*USART初始化*/
	USART_InitTypeDef USART_InitStructure;					//定义结构体变量
	USART_InitStructure.USART_BaudRate = 9600;				//波特率
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;	//硬件流控制，不需要
	USART_InitStructure.USART_Mode = USART_Mode_Tx|USART_Mode_Rx;			//模式，选择收发模式
	USART_InitStructure.USART_Parity = USART_Parity_No;		//奇偶校验，不需要
	USART_InitStructure.USART_StopBits = USART_StopBits_1;	//停止位，选择1位
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;		//字长，选择8位
	USART_Init(USART1, &USART_InitStructure);				//将结构体变量交给USART_Init，配置USART1
	
	/*USART使能*/
	USART_Cmd(USART1, ENABLE);								//使能USART1，串口开始运行
	
	USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//启用USART1，查询中断标志位RXNE，一旦查询到置一，申请终端
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//中断优先级分组
	
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel=USART1_IRQn;//NVIC通道
	NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;//高优先级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;//低优先级
  NVIC_Init(&NVIC_InitStructure);
}

/**
  * 函    数：串口发送一个字节
  * 参    数：Byte 要发送的一个字节
  * 返 回 值：无
  */
void Serial_SendByte(uint8_t Byte)
{
	USART_SendData(USART1, Byte);		//将字节数据写入数据寄存器，写入后USART自动生成时序波形
	while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);	//等待发送完成
	/*下次写入数据寄存器会自动清除发送完成标志位，故此循环后，无需清除标志位*/
}

/**
  * 函    数：串口发送一个数组
  * 参    数：Array 要发送数组的首地址
  * 参    数：Length 要发送数组的长度
  * 返 回 值：无
  */
void Serial_SendArray(uint8_t *Array,uint16_t Length)//发送数组
{
	uint16_t i;
	for(i=0;i<Length;i++)
	{
		
		Serial_SendByte(Array[i]);
	}
}


/**
  * 函    数：串口发送一个字符串
  * 参    数：String 要发送字符串的首地址
  * 返 回 值：无
  */
void Serial_SendString(char *string)
{
	
	uint8_t i;
	for(i=0;string[i]!='\0';i++)
	    {
				Serial_SendByte(string[i]);
			}
}

/**
  * 函    数：次方函数（内部使用）
  * 返 回 值：返回值等于X的Y次方
  */
uint32_t Serial_Pow(uint32_t X, uint32_t Y)
{
	uint32_t Result = 1;	//设置结果初值为1
	while (Y --)			//执行Y次
	{
		Result *= X;		//将X累乘到结果
	}
	return Result;
}

/**
  * 函    数：串口发送数字
  * 参    数：Number 要发送的数字，范围：0~4294967295
  * 参    数：Length 要发送数字的长度，范围：0~10
  * 返 回 值：无
  */
void Serial_SendNumber(uint32_t Number,uint8_t Length)
{
	uint8_t i;
	for(i=0;i<Length;i++)
	{
		Serial_SendByte(Number/Serial_Pow(10,Length-i-1)%10+'0');//由十进制的高位到低位依次发送
	  //加上'0'就转换为ascll码的类型，从ascll码中字符0的位置开始算，也可以改为0x30.
	}
	
}




/**
  * 函    数：使用printf需要重定向的底层函数
  * 参    数：保持原始格式即可，无需变动
  * 返 回 值：保持原始格式即可，无需变动
  */   //将printf的底层重定向到自己的发送字节函数
//什么是重定向？重定向是指将fputc里面的输出指向目标设备。因printf函数调用了fputc，
//而fputc输出有默认指向的目标，且不同库中的fputc输出指向不同,所以需要重写fputc

int fputc(int ch,FILE *f)   //printf重定向，为串口
{
	Serial_SendByte(ch);
	return ch;
}

/**
  * 函    数：自己封装的prinf函数
  * 参    数：format 格式化字符串
  * 参    数：... 可变的参数列表
  * 返 回 值：无
  */
void Serial_Printf(char *format, ...)
{
  char string[100];
	va_list arg;   //参数列表变量
	va_start(arg,format); //
	vsprintf(string,format,arg); 
	va_end(arg);//释放参数表
	Serial_SendString(string);//发送string


}
uint8_t Serial_GetRxFlag()
{
	if(Serial_RxFlag==1)
	{
		Serial_RxFlag=0;
		return 1;
	}
	return 0;
}




//发送stop,go
void USART1_IRQHandler()//串口中断函数
   {
		 uint8_t receive[100];
    	if(USART_GetFlagStatus(USART1,USART_IT_RXNE)==SET)
	   {
		  static uint8_t x=0;
		  uint8_t temp=USART_ReceiveData(USART1);
			  if(temp!='\n')  //字符串接收函数
				{receive[x]=temp;
     	  x++;
				}
				receive[x]='\0';
		  if(strcmp((char*)receive,"stop stm32!")==0)
			{
				receiveFlag=0;
				x=0;
			
			}
			
			else if(strcmp((char*)receive,"go stm32!")==0)
			{
				receiveFlag=1;
				x=0;
			}
			
		  USART_ClearITPendingBit(USART1,USART_IT_RXNE);
	   }
   }
			
	 
	 
	 
	 // 发送s,t
//	 void USART1_IRQHandler()//串口中断函数
//   {
//		 
//    	if(USART_GetFlagStatus(USART1,USART_IT_RXNE)==SET)
//	   { 
//			 uint8_t temp=USART_ReceiveData(USART1);
//			 if(temp=='s')
//			 {
//				 receiveFlag=0;
//			 }
//				 if(temp=='t')
//			 {
//				 receiveFlag=1;
//			 }
//		   
//		  USART_ClearITPendingBit(USART1,USART_IT_RXNE);
//	   }
//   }